package com.qdlc.p2p.biz.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.service.BorrowCollectionService;
import com.qdlc.p2p.biz.service.BorrowService;
import com.qdlc.p2p.common.constant.BorrowCollectionRepayAwardStatus;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.constant.BorrowStyle;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.CollectionUtils;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.model.jpa.OrderFilter.OrderType;
import com.qdlc.p2p.dal.common.model.jpa.PageDataList;
import com.qdlc.p2p.dal.common.model.jpa.QueryParam;
import com.qdlc.p2p.dal.common.model.jpa.SearchFilter;
import com.qdlc.p2p.dal.common.model.jpa.SearchFilter.Operators;
import com.qdlc.p2p.dal.dao.BorrowCollectionDao;
import com.qdlc.p2p.dal.dao.BorrowTenderDao;
import com.qdlc.p2p.dal.dto.Borrow;
import com.qdlc.p2p.dal.dto.BorrowCollection;
import com.qdlc.p2p.dal.dto.BorrowTender;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.model.BorrowCollectionModel;
import com.qdlc.p2p.dal.model.BorrowModel;
import com.qdlc.p2p.dal.model.BorrowTenderModel;
import com.qdlc.p2p.dal.model.interest.EachPlan;
import com.qdlc.p2p.dal.model.interest.InterestCalculator;

@Service("borrowCollectionService")
public class BorrowCollectionServiceImpl implements BorrowCollectionService {

    @Resource
    private BorrowCollectionDao borrowCollectionDao;

    @Resource
    private BorrowTenderDao borrowTenderDao;

    @Resource
    private BorrowService borrowService;

    @Override
    public void save(List<BorrowCollection> list) {
        borrowCollectionDao.save(list);
    }

    @Override
    public double getReceivedInterestSum(long userId) {
        return borrowCollectionDao.getReceivedInterestSum(userId);
    }

    @Override
    public PageDataList<BorrowCollectionModel> list(BorrowCollectionModel model) {
        PageDataList<BorrowCollection> pList = borrowCollectionDao.getList(model);
        PageDataList<BorrowCollectionModel> modelList = new PageDataList<BorrowCollectionModel>();
        List<BorrowCollectionModel> list = new ArrayList<BorrowCollectionModel>();
        modelList.setPage(pList.getPage());
        if (pList.getList().size() > 0) {
            for (int i = 0; i < pList.getList().size(); i++) {
                BorrowCollection c = pList.getList().get(i);
                BorrowCollectionModel cm = BorrowCollectionModel.instance(c);
                cm.setBorrowId(c.getBorrow().getId());
                cm.setBorrowName(c.getBorrow().getName());
                cm.setTimeLimit(c.getBorrow().getTimeLimit());
                cm.setBorrowStyle(c.getBorrow().getStyle());
                cm.setUserName(c.getBorrow().getUser().getUserName());
                cm.setInvestUserName(c.getUser().getUserName());
                cm.setInvestRealName(c.getUser().getRealName());
                cm.setActualInterest(BigDecimalUtil.sub(c.getInterest(), c.getManageFee()));
                cm.setUser(null);
                list.add(cm);
            }
        }
        modelList.setList(list);
        return modelList;
    }

    @Override
    public BorrowCollectionModel getCollectStatistics(long userId) {
        BorrowCollectionModel bm = borrowCollectionDao.getCollectStatistics(userId);
        BorrowCollection bc = borrowCollectionDao.getNextCollectionByUserId(userId);
        if (bc != null) {
            bm.setNextCollectTime(bc.getRepaymentTime());
            bm = borrowCollectionDao.getBCMByCollectTime(bm, bc.getRepaymentTime(), userId);
        }
        double jan = borrowCollectionDao.getCollectByMonth(1, userId);
        double feb = borrowCollectionDao.getCollectByMonth(2, userId);
        double mar = borrowCollectionDao.getCollectByMonth(3, userId);
        double apr = borrowCollectionDao.getCollectByMonth(4, userId);
        double may = borrowCollectionDao.getCollectByMonth(5, userId);
        double jun = borrowCollectionDao.getCollectByMonth(6, userId);
        double jul = borrowCollectionDao.getCollectByMonth(7, userId);
        double aug = borrowCollectionDao.getCollectByMonth(8, userId);
        double sep = borrowCollectionDao.getCollectByMonth(9, userId);
        double oct = borrowCollectionDao.getCollectByMonth(10, userId);
        double nov = borrowCollectionDao.getCollectByMonth(11, userId);
        double dec = borrowCollectionDao.getCollectByMonth(12, userId);
        bm.getCollectData().put("jan", jan);
        bm.getCollectData().put("feb", feb);
        bm.getCollectData().put("mar", mar);
        bm.getCollectData().put("apr", apr);
        bm.getCollectData().put("may", may);
        bm.getCollectData().put("jun", jun);
        bm.getCollectData().put("jul", jul);
        bm.getCollectData().put("aug", aug);
        bm.getCollectData().put("sep", sep);
        bm.getCollectData().put("oct", oct);
        bm.getCollectData().put("nov", nov);
        bm.getCollectData().put("dec", dec);
        return bm;
    }

    @Override
    public List<BorrowCollectionModel> investCollectionList(User user) {
        List<BorrowCollection> pList = borrowCollectionDao.getMemberCollectionList(user);
        List<BorrowCollectionModel> modelList = new ArrayList<BorrowCollectionModel>();
        if (pList.size() > 0) {
            for (int i = 0; i < pList.size(); i++) {
                BorrowCollection c = pList.get(i);
                BorrowCollectionModel cm = BorrowCollectionModel.instance(c);
                cm.setBorrowName(c.getBorrow().getName());
                cm.setUuid(c.getBorrow().getUuid());
                cm.setTimeLimit(c.getBorrow().getTimeLimit());
                cm.setBorrowStyle(c.getBorrow().getStyle());
                cm.setBorrowType(c.getBorrow().getType());
                cm.setUserName(c.getBorrow().getUser().getHideUserName());
                cm.setActualInterest(BigDecimalUtil.sub(c.getInterest(), c.getManageFee()));
                cm.setUser(null);
                modelList.add(cm);
            }
        }
        return modelList;
    }

    @Override
    public double getInterestByUser(User user) {
        return borrowCollectionDao.getInterestByUser(user);
    }

    @Override
    public List<Object[]> getInterestByUserAndDate(User user, String date) {
        return borrowCollectionDao.getInterestByUserAndDate(user, date);
    }

    @Override
    public double getCapitalByUser(User user) {
        return borrowCollectionDao.getCapitalByUser(user);
    }

    @Override
    public List<Object[]> getCapitalByUserAndDate(User user, String date) {
        return borrowCollectionDao.getCapitalByUserAndDate(user, date);
    }

    @Override
    public List<String> getCollectionDate(User user) {
        return borrowCollectionDao.getCollectionDate(user);
    }

    @Override
    public PageDataList<BorrowCollectionModel> getRepayPlanByModel(
            BorrowTenderModel model) {
        Date nowdate = DateUtil.getNow();
        QueryParam param = QueryParam.getInstance();
        param.addParam("user", model.getUser());
        if (model.getStatus() != 0) {
            if (model.getStatus() == -1)
                param.addParam("status", 0);
            else
                param.addParam("status", model.getStatus());
        }
        param.addParam("repaymentTime", Operators.NOTEQ, SearchFilter.NULL);

        //如果此条记录为债权全部转出则不显示记录
        //只判断利息是否全部转出
        //param.addParam("interest", Operators.PROPERTY_NOTEQ, "bondInterest");

        if (StringUtil.isNotBlank(model.getStartTime())) {
            param.addParam("repaymentTime", Operators.GT, DateUtil.valueOf(model.getStartTime()));
        }
        if (StringUtil.isNotBlank(model.getEndTime())) {
            Date date = DateUtil.valueOf(model.getEndTime());
            param.addParam("repaymentTime", Operators.LT, DateUtil.rollDay(date, 1));
        }
        if (model.getTime() == 7) {
            param.addParam("repaymentTime", Operators.LTE, DateUtil.rollDay(nowdate, 7));
            param.addParam("repaymentTime", Operators.GTE, nowdate);
        } else if (model.getTime() > 0 && model.getTime() < 4) {
            param.addParam("repaymentTime", Operators.LTE, DateUtil.rollMon(nowdate, model.getTime()));
            param.addParam("repaymentTime", Operators.GTE, nowdate);
        }
        param.addPage(model.getPage(), model.getSize());
        PageDataList<BorrowCollection> pageList = borrowCollectionDao.findPageList(param);
        List<BorrowCollectionModel> modelList = new ArrayList<BorrowCollectionModel>();
        PageDataList<BorrowCollectionModel> pageDataList = new PageDataList<BorrowCollectionModel>();
        for (BorrowCollection bc : pageList.getList()) {
            BorrowCollectionModel bcm = BorrowCollectionModel.instance(bc);
            Borrow borrow = bc.getBorrow();
            if (borrow.getCategory() == 2) {// 体验标
                bcm.setStartDate(bc.getAddTime());
            } else {
                bcm.setStartDate(borrow.getReviewTime());
            }
            bcm.setBorrowStyle(borrow.getBorrowTimeType());
            bcm.setApr(borrow.getApr());
            bcm.setBorrowName(borrow.getName());
            bcm.setBorrowId(borrow.getId());
            bcm.setBorrowStyle(borrow.getStyle());
            bcm.setBorrowType(borrow.getType());
            int timeLimit = 1;
            if (borrow.getStyle() != BorrowStyle.STYLE_ONETIME_REPAYMENT) {
                timeLimit = borrow.getTimeLimit();
            }
            bcm.setTimeLimit(timeLimit);
            bcm.setTotalCapital(borrowCollectionDao.getTotalCapitalByTenderId(bc.getTender().getId(), model.getUser().getUserId()));
            bcm.setUser(null);
            bcm.setBorrow(null);
            bcm.setUuid(borrow.getUuid());
            if (borrow.getCategory() == 2) {// 体验标;待收本金为0
                bcm.setCapital(0.00);
            }
            modelList.add(bcm);
        }
        pageDataList.setList(modelList);
        pageDataList.setPage(pageList.getPage());
        return pageDataList;
    }

    @Override
    public PageDataList<BorrowCollectionModel> getCurrentRepayPlanByModel(BorrowTenderModel model) {

        /********根据投标ID得到borrow-id  用来查询汇款计划  2015.05.26 start  ctt ****/
        BorrowTender tender = borrowTenderDao.find(model.getId());
//		model.setBorrowId(tender.getBorrow().getId());
        /********根据投标ID得到borrow-id  用来查询汇款计划  2015.05.26 end  ctt   ****/

//		List<BorrowCollection> list = borrowCollectionDao.getCurrentRepayPlanByModel(model);
        QueryParam param = new QueryParam();
        param.addParam("borrow", tender.getBorrow());
        param.addParam("user", model.getUser());
        param.addOrder(OrderType.ASC, "repaymentTime");
        param.addOrder(OrderType.ASC, "addTime");
        param.addPage(model.getPage(), model.getSize());
        PageDataList<BorrowCollection> rtList = borrowCollectionDao.findPageList(param);
        List<BorrowCollectionModel> modelList = new ArrayList<BorrowCollectionModel>();
        PageDataList<BorrowCollectionModel> pageDataList = new PageDataList<BorrowCollectionModel>();
        for (BorrowCollection bc : rtList.getList()) {
            BorrowCollectionModel bcm = BorrowCollectionModel.instance(bc);
            Borrow borrow = bc.getBorrow();
            bcm.setStartDate(borrow.getReviewTime());
            bcm.setBorrowStyle(borrow.getBorrowTimeType());
            bcm.setApr(borrow.getApr());
            bcm.setBorrowName(borrow.getName());
            bcm.setBorrowId(borrow.getId());
            bcm.setBorrowStyle(borrow.getStyle());
            int timeLimit = 1;
            if (borrow.getStyle() != BorrowStyle.STYLE_ONETIME_REPAYMENT) {
                timeLimit = borrow.getTimeLimit();
            }
            bcm.setTimeLimit(timeLimit);
            bcm.setPeriod(bcm.getPeriod() + 1);
            bcm.setTotalCapital(borrowCollectionDao.getTotalCapitalByTenderId(bc.getTender().getId(), model.getUser().getUserId()));
            bcm.setRepaymentAccount(BigDecimalUtil.add(bcm.getRepaymentAccount(), -bcm.getBondCapital(), -bcm.getBondInterest()));
            bcm.setUser(null);
            bcm.setBorrow(null);
            modelList.add(bcm);
        }
        pageDataList.setPage(rtList.getPage());
        pageDataList.setList(modelList);
        return pageDataList;
    }

    @Override
    public Object[] getBorrowCollectionList(long tenderId) {
        return borrowCollectionDao.getBorrowCollectionList(tenderId);
    }

    @Override
    public List<BorrowCollection> createCollectionList(BorrowTender tender, InterestCalculator calculator, double award) {
        List<BorrowCollection> collectList = new ArrayList<BorrowCollection>();
        List<EachPlan> eachPlanList = calculator.getEachPlanList();

        // 拼装Collection对象 批量插入还款表
        int i = 0;
        double totalInterest = 0; //利息总和
        double totalCapital = 0; //本金总和

        double tenderInterest = tender.getInterest();
        double tenderAccount = tender.getAccount();

        if (CollectionUtils.isNotNullOrEmpty(eachPlanList)) {
            int eachPlanLastSize = eachPlanList.size() - 1;
            for (EachPlan eachPlan : eachPlanList) {
                BorrowCollection borrowCollection = buildBorrowCollection(eachPlan, tender);
                if (i == eachPlanLastSize) { // 最后一期做减法(利息做减法，本金做减法，生成最后一期的待收本金，待收利息)
                    //计算最后一期利息
                    double different = BigDecimalUtil.sub(tenderInterest, totalInterest);
                    borrowCollection.setInterest(different);

                    //计算最后一期本金
                    double differentCapital = BigDecimalUtil.sub(tenderAccount, totalCapital);
                    borrowCollection.setCapital(differentCapital);
                    borrowCollection.setRepaymentAccount(BigDecimalUtil.add(differentCapital, different));
                }
                totalInterest = BigDecimalUtil.add(totalInterest, eachPlan.getInterest());
                totalCapital = BigDecimalUtil.add(totalCapital, eachPlan.getCapital());
                borrowCollection.setPeriod(i++);

                Date repaymentTime = borrowService
                        .getRepayTime(BorrowModel.instance(tender.getBorrow()), borrowCollection.getPeriod());
                borrowCollection.setRepaymentTime(repaymentTime);
                borrowCollection.setRepayAward(award);
                borrowCollection.setRepayAwardStatus(BorrowCollectionRepayAwardStatus.RECEIVED);
                collectList.add(borrowCollection);
            }
        }

        if (CollectionUtils.isNotNullOrEmpty(collectList)) {
            this.save(collectList);
        }
        return collectList;
    }

    /**
     * 拼装借款代收信息
     *
     * @param tender   投标
     * @param eachPlan 每期还款计划
     * @author Kaiju Zhao
     */
    private BorrowCollection buildBorrowCollection(EachPlan eachPlan, BorrowTender tender) {
        BorrowCollection borrowCollection = new BorrowCollection();
        borrowCollection.setBorrow(tender.getBorrow());
        borrowCollection.setTender(tender);
        borrowCollection.setInterest(eachPlan.getInterest());
        borrowCollection.setCapital(eachPlan.getCapital());
        borrowCollection.setRepaymentAccount(eachPlan.getTotal());
        borrowCollection.setAddTime(DateUtil.getNow());
        borrowCollection.setAddIp(Global.getIP());
        borrowCollection.setStatus(0);
        borrowCollection.setRepaymentYesAccount(0.00);
        borrowCollection.setLateDays(0);
        borrowCollection.setLateInterest(0.00);
        borrowCollection.setUser(tender.getUser());
        double borrowFee = SystemConfigHelper.getDoubleValue(SystemConfigHelper.Nid.INVESTOR_MANAGE_FEE);
        borrowFee = BigDecimalUtil.mul(borrowCollection.getInterest(), BigDecimalUtil.div(borrowFee, 100));
        borrowFee = BigDecimalUtil.round(borrowFee); // 四舍五入
        borrowCollection.setManageFee(borrowFee);
        return borrowCollection;
    }

    @Override
    public List<Object[]> getInterestByMonth(long userId, String startDate) {
        return borrowCollectionDao.getInterestByMonth(userId, startDate);
    }

    @Override
    public double getAmountInterestByMonth(long userId, String startDate) {
        return borrowCollectionDao.getAmountInterestByMonth(userId, startDate);
    }

    @Override
    public double getAmountRepaymentByMonth(long userId, String startDate) {
        return borrowCollectionDao.getAmountRepaymentByMonth(userId, startDate);
    }
}
